<style lang='scss'>
#js-zookeeper{
  .node-name-input{
    width: 300px;
  }
  .url-path{
    border-bottom: 1px solid;
    margin: 0 5px;
  }
  .add-header{
    margin-bottom: 10px;
    display: flex;
    .item{
      width: 50%;
      &:nth-of-type(1){
        margin-top: 10px
      }
    } 
  }
  .copy-tree{
    height: 432px;
    overflow: auto;
    border: 1px solid rgb(204, 204, 204);
    width: 60%
  }
  .content-text{
    display: inline-block;
    cursor:default;
    font-size:14px;
    margin-right: 15px;
  }
  .edit-node{
    cursor:default;
    font-size:14px;
    margin-top:10px
  }
  .copy-node{
    margin-bottom: 15px;
    .el-input{
      width: calc(100% - 100px)
    }
  }
}
</style>
<template>
  <div id="js-zookeeper">
    <Box>
      <!-- {{firstLevelNode}}
      
      {{newNode}} -->
    <div style="background-color:white;">
      <el-row class="mb20">
        <el-select @change="handleNodeTypeChange" placeholder="请选择节点类型" v-model="nodeType">
          <el-option v-for="item in nodeTypeOpts" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
        <el-button
          :disabled="getCheckedKeysSum == 0"
          type="danger"
          size="small"
          icon="el-icon-delete"
          @click="onDelRecord({type:'batchDel',data:modifyForm})"
        >批量删除末节点</el-button>
        <el-button type="primary" size="small" icon="el-icon-plus" @click="addNode()" v-if="currentParentPath">新增节点</el-button>
        <el-select placeholder="请选择环境" v-model="envType">
          <el-option v-for="item in envOpts" :key="item.value" :label="item.label" :value="item.value"></el-option>
        </el-select>
        <el-button type="primary" size="small" icon="el-icon-delete" @click="uploadSync({type:'upload'})">上传</el-button>
        <el-input placeholder="请输入同步文件名称" v-model="uploadFileName" style="width:200px;"></el-input>
        <el-button type="primary" size="small" icon="el-icon-delete" @click="uploadSync({type:'sync'})">同步</el-button>
      </el-row>
      <el-row>
        <span class="content-text" >{{"内容对应路径："+ (modifyForm.key || '')}}</span>
        <el-button type="primary" size="small" @click="copyNode()" v-if="currentParentPath">复制节点</el-button>
      </el-row>
       <div class="edit-node" style="" v-if="modifyForm.key">
          <span>编辑节点：</span>
          <el-input v-model="newNode" style="width:600px"></el-input>
          <el-button type="primary" @click="changeNodeName">确定</el-button>
        </div>
      <!-- <div>
        编辑节点名称：
        原节点名称：<el-input ></el-input>
        修改为：<el-input></el-input>
      </div> -->
      <el-row v-if="uploadFileName">
        <span style="cursor:default;font-size:14px;">{{"可以同步的文件是："+ (uploadFileName || '')}}</span>
      </el-row>

      <el-form class="mt20" style="width:100%;" :model="modifyForm" ref="modifyForm" label-width="80px">
        <el-row>
          <el-col :span="12" class="permission-menu" style="height: 432px; overflow: auto; border:1px solid #ccc;">
            <div>
              <el-tree
                class="filter-tree"
                :data="assetMenuTreeData"
                node-key="path"
                ref="tree"
                :default-expanded-keys="firstLevelNode"
                :highlight-current="true"
                show-checkbox
                @check-change="handlerCheckChange"
                @node-click="handleNodeClick"
                :props="defaultProps"
              ></el-tree>
            </div>
          </el-col>

          <el-col :span="12">
            <el-form-item label="content:">
              <!-- <div id="container" style="margin-left:1px;min-height:430px;border:1px solid rgb(204, 204, 204)"></div> -->
              <MonacoEditor :jsonData.sync="modifyForm.content" key="jsonData" ref="jsonData" v-if="!addSyncDialogVisible"></MonacoEditor>
              <!-- <el-input type="textarea" :autosize="{minRows:20}" placeholder="请输入" v-model="modifyForm.content"></el-input> -->
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="24" class="tc mt20">
            <el-button icon="el-icon-edit"  type="success" @click="confirmEdit({type:'edit',data:modifyForm })">编辑</el-button>
            <el-button
              icon="el-icon-delete"
              :disabled="getCheckedKeysSum != 1"
              type="danger"
              @click="onDelRecord({type:'del',data:modifyForm})"
            >删除</el-button>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <el-dialog
      :close-on-click-modal="false"
      :title="syncTitle"
      @close="syncDialogVisible = false;"
      :visible.sync="syncDialogVisible"
      class="view-dialog"
    >
      <div v-if="syncTitle == '文件同步完成' " style="display:flex;">
        <h5>成功的文件数:{{fileList.successCount}}</h5>
        <h5 style="margin-left:20px;">失败的的文件数:{{fileList.faildCount}}</h5>
      </div>
      <el-table
        v-loading="regionLoading"
        element-loading-spinner="el-icon-loading"
        :data="fileList.data"
        border
        style="width:100%"
        class="m20px"
        ref="multipleTable"
        max-height="500">
        <el-table-column :prop="fileList.key[0]" :label="fileList.key[0]"></el-table-column>
        <el-table-column :prop="fileList.key[1]" :label="fileList.key[1]"></el-table-column>
      </el-table>

      <el-row class="tc mt20">
        <el-button v-if="syncTitle == '文件同步' " type="primary" size="small" @click="confirmSync">确认同步</el-button>
        <el-button v-if="syncTitle == '文件同步完成' " type="primary" size="small" @click="syncFinished">关闭</el-button>
      </el-row>
    </el-dialog>
    <el-dialog 
      :close-on-click-modal="false"
      title="新增节点"
      @close="addSyncDialogVisible = false;"
      top="10vh"
      :visible.sync="addSyncDialogVisible">
      <div class="add-header">
        <div class="item"> 
          <span class="url">url:</span>
          <span class="url-path">{{currentParentPath}}</span> 
        </div>
        <div class="item">
          <span class="node-name">name:</span>
          <el-input :minlength="200" class="node-name-input" v-model="addForm.name"></el-input>
        </div>
      </div>
      <MonacoEditor :jsonData.sync="addForm.content" key="jsonData1" ref="jsonData1" v-if="addSyncDialogVisible"></MonacoEditor>
      <div class="mt20 tc">
        <el-button type="primary" size="small" @click="saveAddNode">保存</el-button>
        <el-button type="primary" size="small" @click="addSyncDialogVisible = false;">取消</el-button>
      </div>
    </el-dialog>
    <el-dialog 
      :close-on-click-modal="false"
      title="复制节点"
      @close="cloneSyncDialogVisible = false;"
      top="10vh"
      width="80%"
      :visible.sync="cloneSyncDialogVisible">
      <div>
        <div class="copy-node">
          <span>sourcePath：</span>
          <span>{{this.modifyForm.key}}</span>
        </div>
        <div class="copy-node">
          <span>targetPath：</span>
          <el-input v-model="newTargetPath" placeholder=""></el-input>
        </div>
        <div class="tc">
          <el-button type="primary" size="small" @click="saveCopyNode">保存</el-button>
          <el-button type="primary" size="small" @click="cloneSyncDialogVisible = false;">取消</el-button>
        </div>
      </div>
    </el-dialog>
    </Box>
  </div>
</template>
<script>


import { mapGetters, mapActions, mapState, mapMutations } from "vuex";
import { isJSON, sendReq, GetQueryString } from 'src/utils/tools';
import notification from "src/utils/notification";
import fetch from "src/utils/fetch";
import MonacoEditor from "src/components/common/MonacoEditor.vue"
//=======================树形图分级要用======================================================
function compare(property) {
  return function (a, b) {
    var val1 = a[property];
    var val2 = b[property];
    if (val1 < val2) {
      return -1;
    } else if (val1 > val2) {
      return 1;
    } else {
      return 0;
    }
  }
}

function deepOrderByProp(src, destObj) {
  let dest = destObj || [];

  // 遍历属性值,判断是否为json字符串
  src.forEach((item, index) => {
    //是json字符串,进行json格式化
    if (item.childNodeInfo.length > 0) {
      let childNodeInfo = item.childNodeInfo.sort(compare('path'));
      dest[index] = item;
      dest[index].childNodeInfo = childNodeInfo;
      deepOrderByProp(dest[index].childNodeInfo, dest[index]);
    }
    else {
      dest[index] = item;
    }
  })
  return dest;
}
//==========================================================================
export default {
  data() {
    const inputWarning = (msg) => {
      return [
        {
          required: true,
          message: msg,
          trigger: "blur,change"
        }
      ];
    };
    return {
      fileList: {
        data: [],
        key: [],
      },
      modifyForm: {
        content:''
      },
      syncTitle: '',
      syncDialogVisible: false,
      uploadFileName: '',
      nodeType: 'asset',
      envType: 'test',
      envOpts: [
        { label: 'test', value: 'test' },
        { label: 'uat', value: 'uat' },
        { label: 'prd', value: 'prd' },
      ],
      nodeTypeOpts: [
        { label: 'asset', value: 'asset' },
        { label: 'plouto', value: 'plouto' },
      ],

      defaultProps: {
        children: "childNodeInfo",
        label: "path",
      },
      getCheckedKeysSum: 0,
      assetMenuTreeData: [],
      firstLevelNode: [],
      isNoData: true,
      
      currentAllPath:'',
      addSyncDialogVisible:false,
      currentParentPath:'',
      addForm:{
        content:"",
        name:''
      },
      cloneSyncDialogVisible:false,
      newNode:'',
      newTargetPath:''
    };
  },
  components: {
    MonacoEditor
  },
  watch:{
    addSyncDialogVisible:function(){
      // if(val){
      //   this.$refs.jsonData1.initEditor();
      // }else{
      //   this.$refs.jsonData.initEditor();
      // }
    }
    
  },
  computed: {
    ...mapGetters(["regionLoading", 'pagination']),
  },
  created() {
    this.doFullDataQuery();
  },
  mounted() {
  },
  methods: {
    assetActionCB(path){
      let that = this;
      return {
        key: '/' + path,
        cb: (data) => {
         
          this.assetMenuTreeData = [{ path: path, parentPath: '/', childNodeInfo: deepOrderByProp(data.sort(compare('path'))) }];
          this.isNoData = true;
          this.modifyForm.content = '';
          this.getCheckedKeysSum = 0;
          that.$nextTick(_ => {
            that.$refs.tree.setCurrentKey(that.firstLevelNode.join());
            if(that.firstLevelNode.length != 0){
              that.operateJson(that.currentAllPath);
            }
          })
        }
      }
    },
    ...mapActions(["doZooHandlerName",]),

    syncFinished() {
      this.syncDialogVisible = false;
      this.uploadFileName = '';
    },
    confirmSync() {
      this.$confirm("确定要同步文件" + this.uploadFileName + "吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.uploadSync({ type: 'confirmSync' });
      })
    },
    uploadSync(obj) {

      let { type } = obj;
      let key = this.getCheckedNodes();
      let params = {};
      if (type == 'upload') {

        if (key.length == 0) {
          return notification.warning('请先勾选要同步的文件树节点');
        }
        params = {
          url: '/circulation/uploadConfigOss',
          args: {
            pathList: key,
            ambient: this.envType,
          },
          cb: (data) => {
            this.uploadFileName = data;
            notification.success(`可以同步的文件是\n${data}`, '操作成功');
          }
        }

      } else if (type == 'sync') {

        params = {
          url: '/circulation/getCompInfo',
          args: {
            fileName: this.uploadFileName,
            ambient: this.envType,
          },
          cb: (data) => {

            if (!data) return;

            this.syncTitle = "文件同步";
            this.syncDialogVisible = true;
            this.arrToList(data, ['add', 'update']);

          }
        }
      } else if (type == 'confirmSync') {

        this.syncDialogVisible = false;
        params = {
          url: '/circulation/setConfig',
          args: {
            fileName: this.uploadFileName,
            ambient: this.envType,
          },
          cb: (data) => {
            if (!data) return;
            this.syncTitle = "文件同步完成";
            this.syncDialogVisible = true;
            this.fileList.successCount = data.success.length;
            this.fileList.faildCount = data.faild.length;
            this.arrToList(data, ['success', 'faild']);
          }

        }

      }

      sendReq({
        url: params.url,
        params: params.args,
        cb: (data) => {
          params.cb(data);
        }
      })
    },
    arrToList(data, keys) {

      data[keys[0]] = data[keys[0]] ? data[keys[0]] : [];
      data[keys[1]] = data[keys[1]] ? data[keys[1]] : [];

      let max = Math.max(data[keys[1]].length, data[keys[0]].length);
      this.fileList.key = keys;
      for (let i = 0; i < max; i++) {
        this.fileList.data[i] = { update: '', add: '' };
        if (data[keys[0]].length > 0 && data[keys[0]][i]) {
          this.fileList.data[i][keys[0]] = data[keys[0]][i];
        }
        if (data[keys[1]].length > 0 && data[keys[1]][i]) {
          this.fileList.data[i][keys[1]] = data[keys[1]][i];
        }
      }
    },
    handleNodeTypeChange() {
      this.assetNodeQuery();
    },

    addHistoryRouter(row, cb) {
      let params = {
        path: row.path ? row.path : row.key,
        content: row.content ? row.content : '',
        operateAction: row.operateAction,
      };

      fetch({
        url: '/zkdata/history',
        type: "post",
        data: params,
        showRegionLoading: true,
        success: (data) => {
          cb && cb(row);
        }
      });
    },
    getCheckedNodes() {
      let keys = [];
      // 获取叶子节点选中项
      this.$refs.tree.getCheckedNodes().forEach((node, index) => {
        // 过滤掉根节点
        if (node.childNodeInfo.length == 0) {
          keys.push(node.parentPath + node.path);
        }
      });
      return keys;
    },
    handleNodeClick(data, node, components) {
      let key = data.parentPath + data.path;
      this.newNode = data.path;
      this.modifyForm.key = key;
      this.firstLevelNode = [data.path];
      this.currentAllPath = key;
      this.operateJson(key);
      if(data.childNodeInfo.length == 0){
        this.currentParentPath = data.parentPath
      }else{
        this.currentParentPath = this.currentAllPath;
      }
      
    },
    operateJson(key){
      fetch({
        url: '/config/showValue',
        type: "post",
        data: { key:key},
        showRegionLoading: true,
        success: (data) => {
          if (data && data[key]) {
            this.isNoData = false;
            // 是json格式则进行美化,非json格式,原样展示
            let jsonObj = isJSON(data[key], '', true) ? JSON.stringify(JSON.parse(data[key]), '{}', 4) : data[key];
            //this.$set(this.modifyForm, 'content', jsonObj);
            this.modifyForm.content = jsonObj;
            this.$nextTick(_ =>{
              this.$refs.jsonData.initEditor();
            })
          } else {
            this.isNoData = true;
            this.modifyForm.content  = '' ;
            //this.$set(this.modifyForm, 'content', '');
          }
        },
      });
    },
    handlerCheckChange() {
      this.getCheckedKeysSum = this.getCheckedNodes().length;
    },
    assetNodeQuery(isEditNode=false) {
      let that = this;
      sendReq({
        url: '/config/queryNodeInfo',
        params: { key: '/' + that.nodeType },
        cb: (data) => {
          that.firstLevelNode = [that.nodeType];
          that.assetMenuTreeData = [{ path: that.nodeType, parentPath: '/', childNodeInfo: deepOrderByProp(data.sort(compare('path'))) }];
          console.log(isEditNode)

          if(isEditNode){
            that.firstLevelNode = [that.newNode];
            that.$nextTick(e => {
              that.$refs.tree.setCurrentKey(that.newNode);
            })
          }
        }
      })
    },
    doFullDataQuery(isEditNode=false) {
      this.assetNodeQuery(isEditNode);
    },
    confirmEdit(param) {
      param.data.content = this.$refs.jsonData.getJsonData();
      this.$confirm("确认对" + (param.data.key || '') + "进行编辑操作?", "提示")
        .then(() => {
          this.onSubmitForm(param, '编辑');
        })
        .catch(() => {
          this.$message.info('你已取消该操作!');
        });
    },

    //新增&&编辑保存
    onSubmitForm(param, actionType) {

      let params = JSON.parse(JSON.stringify(param));
      params.queryParams = this.queryParams;

      // zookeeper asset页面新增router和handler判断逻辑
      if (this.$route.name == 'zooKeeper配置') {
        // 判断节点内容区是不是json字符串,如果不是，不保存
        // if (!isJSON(param.data.content, '内容不是标准的JSON格式,请检查提交的content内容!')) {
        //   return;
        // }
        params.queryParams = this.assetActionCB(this.nodeType);
        this.$refs.tree.setCurrentKey(this.firstLevelNode.join())
      }

      this.$refs.modifyForm.validate(valid => {
        if (valid) {
          params.cb = () => {
            this.modifyDialogVisible = false;
            // 添加历史版本操作
            params.data.operateAction = actionType || {
              'add': '新增',
              'edit': '修改',
            }[this.editType];

            // console.log(params.operateAction);

            this.addHistoryRouter(params.data, () => { });
            // }
          };

          console.log('params', params);

          this.doZooHandlerName(params);

        } else {
          this.$message({
            type: "warning",
            message: "请检查表单必填项!"
          });
        }
      });
    },
    // 删除
    onDelRecord(param) {
      let params = JSON.parse(JSON.stringify(param));
      let key = this.getCheckedNodes();
      if (params.type == 'del') {
        params.data.key = key[0] ? key[0] : '';
      } else if (params.type == 'batchDel') {
        params.data = key ? key : '';
      }
      params.queryParams = this.assetActionCB(this.nodeType);
      params.cb = () => {
        // 添加历史版本操作
        params.data.operateAction = '删除';
        this.addHistoryRouter(params.data, () => { });

      };
      this.$confirm("确定要删除这" + (params.type == 'batchDel' ? '些' : "条") + "记录吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.doZooHandlerName({ ...params });
      }).catch(() => {
        this.$message({
          type: "info",
          message: "已取消删除"
        });
      });
    },
    addNode(){
      this.addSyncDialogVisible = true;
      this.resetAddForm();
    },
    resetAddForm(){
      this.addForm = {
        name:'',
        content:""
      }
    },
    saveAddNode(){
      let content = this.$refs.jsonData1.getJsonData();
      if(!isJSON(content)){
        return
      }
      let str = this.currentParentPath;
      if(str.substring(str.length-1,str.length) == "/"){
        str = str.substring(0,str.length-1);
      }
      let params = {
        content:JSON.parse(content),
        productCode:this.$route.params.productCode,
        // name:this.addForm.name,
        path:str+'/'+this.addForm.name
      }
      this.$confirm("确定要提交新增节点：" + this.addForm.name, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        fetch({
          url: '/config/updateNode',
          type: "post",
          data: params,
          success: (data) => {
            this.doFullDataQuery(true);
            this.$message({
              type: "info",
              message: "保存成功"
            });
            this.addSyncDialogVisible = false;
            this.resetAddForm();
          }
        });
      }).catch(() => {
        this.$message({
          type: "info",
          message: "已取消提交"
        });
      });
      

    },
    copyNode(){
      this.cloneSyncDialogVisible = true;
      this.newTargetPath = this.modifyForm.key;
    },
    changeNodeName(){
      let path = this.currentAllPath;
      this.$confirm("确定要提交编辑节点：" + this.newNode, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        fetch({
          url: '/config/renameNode',
          type: "post",
          data: {
            path,
            newName:this.newNode
          },
          success: (data) => {
            this.$message({
              type: "success",
              message: "修改成功"
            });
            this.doFullDataQuery(true);
          }
        })
      }).catch(() => {
        this.$message({
          type: "info",
          message: "已取消提交"
        });
      });
    },
    saveCopyNode(){
      let sourcePath = this.currentAllPath;
      this.$confirm("确定要提交复制/编辑的节点：" + this.newTargetPath, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        fetch({
          url: '/config/cloneNode',
          type: "post",
          data: {
            sourcePath,
            targetPath:this.newTargetPath
          },
          success: (data) => {
            this.cloneSyncDialogVisible = false;
            this.$message({
              type: "success",
              message: "复制成功"
            });
            this.doFullDataQuery(true);
          }
        })
      }).catch(() => {
        this.$message({
          type: "info",
          message: "已取消提交"
        });
      });
    }
  }
};
</script>
